package com.davidk.survey.server.data;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceException;

import com.davidk.survey.server.DataRequest;
import com.davidk.survey.server.DataSourceInterface;
import com.davidk.survey.server.model.smartgwtrest.Response;
import com.davidk.survey.server.model.smartgwtrest.ErrorResponse;
import com.davidk.survey.server.model.smartgwtrest.FetchResponse;

public class BaseDAO<T> implements DataSourceInterface {
	public BaseDAO(String className) {
		super();
		this.className = className;
	}

	String className;

	public String getClassName() {
		return className;
	}

	@SuppressWarnings("unchecked")
	@Deprecated
	public List<T> list() {
		EntityManager em = EMF.get().createEntityManager();
		List<T> ret = new ArrayList<T>();
		try {
			javax.persistence.Query query = em.createQuery("select p from " + className + " p ");
			ret.addAll(query.getResultList());
			return Collections.unmodifiableList(ret);
		} catch (PersistenceException pex) {
			pex.printStackTrace(System.out);
		} finally {
			em.close();
		}
		return null;
	}

	@SuppressWarnings("unchecked")
	@Deprecated
	public List<T> getByKey(String keyName, String keyValue) {
		EntityManager em = EMF.get().createEntityManager();
		List<T> ret = new ArrayList<T>();
		try {
			javax.persistence.Query query = em.createQuery("select p from " + className + " p where p." + keyName
					+ "='" + keyValue + "'");
			ret.addAll(query.getResultList());
			return Collections.unmodifiableList(ret);
		} catch (PersistenceException pex) {
			pex.printStackTrace(System.out);
		} finally {
			em.close();
		}
		return null;
	}

	@SuppressWarnings("unchecked")
	public List<T> getByKey(String className, String keyName, long keyValue) {
		EntityManager em = EMF.get().createEntityManager();
		List<T> ret = new ArrayList<T>();
		try {
			javax.persistence.Query query = em.createQuery("select p from " + className + " p where p." + keyName + "="
					+ keyValue);
			ret.addAll(query.getResultList());
			return Collections.unmodifiableList(ret);
		} catch (PersistenceException pex) {
			pex.printStackTrace(System.out);
		} finally {
			em.close();
		}
		return null;
	}

	public void saveObj(T user) throws DataStoreException {
		EntityManager em = EMF.get().createEntityManager();
		try {
			em.merge(user);
		} catch (Exception ex) {
			System.err.println("saveObj error : ");
			ex.printStackTrace(System.err);
			throw new DataStoreException(ex);
		} finally {
			em.close();
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	public Response fetch(DataRequest request) {
		EntityManager em = EMF.get().createEntityManager();

		try {
			FetchResponse<T> res = new FetchResponse<T>();
			List<T> ret = new ArrayList<T>();
			javax.persistence.Query query = em.createQuery("select p from " + className + " p ");
			ret.addAll(query.getResultList());
			res.setData(ret);
			return res;
		} catch (PersistenceException pex) {
			pex.printStackTrace(System.out);
			return new ErrorResponse(Response.STATUS_FAILURE, "DB Error : " + pex.getMessage());
		} finally {
			em.close();
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	public Response add(DataRequest request, Object data) {
		EntityManager em = EMF.get().createEntityManager();
		try {
			em.persist((T)data);
		} catch (Exception ex) {
			System.err.println("saveObj error : ");
			ex.printStackTrace(System.err);
			return new ErrorResponse(Response.STATUS_FAILURE, "DB Error : " + ex.getMessage());
		} finally {
			em.close();
		}
		return new Response();
	}

	@SuppressWarnings("unchecked")
	@Override
	public Response update(DataRequest request, Object data) {
		EntityManager em = EMF.get().createEntityManager();
		try {
			em.merge((T) data);
		} catch (Exception ex) {
			System.err.println("saveObj error : ");
			ex.printStackTrace(System.err);
			return new ErrorResponse(Response.STATUS_FAILURE, "DB Error : " + ex.getMessage());
		} finally {
			em.close();
		}
		return new Response();
	}

	@SuppressWarnings("unchecked")
	@Override
	public Response remove(DataRequest request, Object data) {
		EntityManager em = EMF.get().createEntityManager();
		try {
			em.remove((T) data);
		} catch (Exception ex) {
			System.err.println("remove error : ");
			ex.printStackTrace(System.err);
			return new ErrorResponse(Response.STATUS_FAILURE, "DB Error : " + ex.getMessage());
		} finally {
			em.close();
		}
		return new Response();
	}
}
